package com.ee.chat.api.task;

import com.ee.chat.api.common.CommonService;
import com.ee.chat.common.dao.UserCallLogMapper;
import com.ee.chat.common.dao.UserExpandMapper;
import com.ee.chat.common.dao.UserMapper;
import com.ee.chat.common.entity.UserCallLog;
import com.ee.chat.common.entity.UserExpand;
import com.ee.chat.common.serconfig.MyNeteaseApp;
import com.ee.chat.common.service.IGeneralService;
import com.ee.chat.common.service.IUpdateEntityService;
import com.ee.chat.common.util.ConstantsUtil;
import com.ndhutu.ee.util.StringUtil;
import com.ndhutu.ee.util.netease.im.IMUtil;
import com.ndhutu.ee.util.netease.vod.VodUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author Shane
 * @Date 2020/7/13 22:57
 */
@Component
public class MsgTask{
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    UserMapper userMapper;
    @Resource
    MyNeteaseApp app;
    @Resource
    CommonService commonService;
    @Resource(name = "stringRedisTemplate")
    StringRedisTemplate redisTemplate;
    @Resource
    UserExpandMapper userExpandMapper;
    @Resource
    IGeneralService generalService;
    @Resource
    UserCallLogMapper userCallLogMapper;
    @Resource
    IUpdateEntityService updateEntityService;

    /**
     * 不定时让在线主播给在线用户发消息
     * @Author Shane
     * @Date 2020/7/13 22:59
     * @param
     * @return
     */
//    @Scheduled(cron = "0/30 * * * * ?")
    public void sendMsg() throws Exception{
        if(!commonService.getIpStatus()){
            return;
        }

        //偏移
        long r = (int) (Math.random() * 5000);
        Thread.sleep(r);

        //在线的用户
        List<Integer> userIds = userMapper.getOnlineUser(3);
        if(userIds.size() == 0){
            return;
        }

        //在线的主播
        List<Map<String, Object>> hosts = userMapper.getOnlineHost(3);
        if(hosts.size() == 0){
            return;
        }
        int count = userMapper.getOnlineHostCount(3);
        if(count <= 0){
            return;
        }


        int size = hosts.size();
        for(Integer userId : userIds){
            //判断次数，在线时间内，最多系统推送10条消息
            String key = ConstantsUtil.USER_ONLINE + userId;
            Map<Object, Object> map = redisTemplate.opsForHash().entries(key);
            if(map == null || map.size() == 0){
                continue;
            }
            int imNum = map.get("imNum") == null ? 0 : Integer.parseInt(map.get("imNum")+"");
            if(imNum >= 9){
                //更新标记
                UserExpand userExpand = userExpandMapper.selectByUserId(userId);
                if(userExpand == null){
                    userExpand = new UserExpand();
                    userExpand.setUserId(userId);
                }
                userExpand.setAutoPushIm(1);
                updateEntityService.updateUserExpand(userExpand);

                continue;
            }

            int random = (int)(Math.random() * size);
            Map<String, Object> host = hosts.get(random);



            Integer hostUserId = Integer.parseInt(host.get("userId")+"");
            String content = host.get("content")+"";

            //发送消息
            Map<String, Object> data = IMUtil.sendMsg(app.getIdPrefix()+hostUserId, app.getIdPrefix()+userId, content, app);
            String msgid = data.get("msgid")+"";
            if(!StringUtil.isEmpty(msgid)){
                String k = ConstantsUtil.USER_IM + "msgid:" + msgid;
                redisTemplate.opsForHash().put(k, "is_sys", "2");

                redisTemplate.expire(k, 1, TimeUnit.MINUTES);
            }

            //更新发送次数
            imNum ++;
            map.put("imNum", imNum+"");
            redisTemplate.boundHashOps(key).putAll(map);
        }
    }

    /**
     * 定时删除超过7天视频内容（每天凌晨4点执行）
     * @Author Shane
     * @Date 2020/8/26 22:32
     * @param
     * @return
     */
    @Scheduled(cron = "0 0 4 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void delVideo() throws Exception{
        if(!commonService.getIpStatus()){
            return;
        }

        LocalDateTime time = LocalDateTime.now();
        time = time.minusDays(7);
        Date date = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
        List<Map<String, Object>> videos = userCallLogMapper.getDeleteVids(date);

        int max = 50;
        List<Map<String, Object>> temps = new ArrayList<>();
        for(int i=1, size=videos.size(); i<size; i++){
            temps.add(videos.get(i-1));

            if(i % max == 0){
                //批量删除原文件
                VodUtil.delete(temps, app);

                //更新删除状态
                for(Map<String, Object> temp : temps){
                    UserCallLog UserCallLog = new UserCallLog();
                    UserCallLog.setId(Integer.parseInt(temp.get("id")+""));
                    UserCallLog.setVstatus(1);
                    userCallLogMapper.updateById(UserCallLog);
                }

                temps = new ArrayList<>();
            }
        }

        if(temps.size() > 0){
            //批量删除原文件
            VodUtil.delete(temps, app);

            //更新删除状态
            for(Map<String, Object> temp : temps){
                UserCallLog userCallLog = new UserCallLog();
                userCallLog.setId(Integer.parseInt(temp.get("id")+""));
                userCallLog.setVstatus(1);
                userCallLogMapper.updateById(userCallLog);
            }
        }
    }

    /**
     * websocket心跳包，每分钟执行一次
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void sendHeartbeat(){
        if(!commonService.getIpStatus()){
            return;
        }

        Map<String, Object> message = new HashMap<>();
        message.put("operationId", 0);

        generalService.pushUserOperations(ConstantsUtil.USER_WS_OPERATION, message);
    }
}

